package org.jeecg.config.deepseek;

import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.deepseek.pojo.ChatRequest;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.model.ModelOptionsUtils;
import org.springframework.ai.model.function.FunctionCallback;
import org.springframework.ai.model.tool.ToolCallingChatOptions;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.ai.openai.api.OpenAiApi;
import org.springframework.ai.openai.api.ResponseFormat;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.ai.tool.resolution.SpringBeanToolCallbackResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Supplier;

@Slf4j
@Component
public class ChatRequestBean {

    private Method method;
    private OpenAiChatModel deepseekChatModel;

    private Prompt prompt;

    private  List<OpenAiApi.FunctionTool> tools;

    @Autowired
    private ApplicationContext applicationContext;

    private Map<String, ToolCallback> toolCallbackMap;

    public ChatRequestBean(OpenAiChatModel deepseekChatModel) {
        this.deepseekChatModel = deepseekChatModel;
    }
//    public OpenAiApi.ChatCompletionRequest createChatRequest(String userMessage) throws Exception {
//        ChatRequest.Message system = new ChatRequest.Message("system", "你是公司内部的AI助手，请格式化输出内容到html的<body>标签中");
//        ChatRequest.Message user = new ChatRequest.Message("user", userMessage);
//
//        if (method == null) {
//            method = OpenAiChatModel.class.getDeclaredMethod("createRequest", Prompt.class, boolean.class);
//            method.setAccessible(true);
//        }
//
//        Prompt prompt = new Prompt(userMessage, OpenAiChatOptions.builder()
//                .responseFormat(ResponseFormat.builder()
//                        .type(ResponseFormat.Type.TEXT)
//                        .build())
//                .functions(Set.of("searchTeachersByName", "queryTeachersCount"))
//                .build());
//
//        return (OpenAiApi.ChatCompletionRequest) method.invoke(deepseekChatModel, prompt, false);
//    }
    public OpenAiApi.ChatCompletionRequest createChatRequestFunction() throws Exception {
        if (method == null) {
            method = OpenAiChatModel.class.getDeclaredMethod("createRequest", Prompt.class, boolean.class);
            method.setAccessible(true);
        }
        System.out.println("method = " + method);
        Prompt prompt = new Prompt("你是公司内部的AI助手，请格式化输出内容到html的<body>标签中", OpenAiChatOptions.builder()
                .responseFormat(ResponseFormat.builder()
                        .type(ResponseFormat.Type.JSON_SCHEMA)
                        .build())
//                .toolNames("Set.of("getWebjbinfoBySelected","getWebTeamMxBySelected","getWebSchoolMxBySelected")")
                .build());
        OpenAiApi.ChatCompletionRequest chatRequest = (OpenAiApi.ChatCompletionRequest) method.invoke(deepseekChatModel, prompt, false);
        this.tools=chatRequest.tools();
        return chatRequest;
    }


    public OpenAiApi.ChatCompletionRequest createChatRequestFunction1() throws Exception {
//        ChatRequest.Message system = new ChatRequest.Message("system", "你是公司内部的AI助手，请格式化输出内容到html的<body>标签中");
        if (method == null) {
            method = OpenAiChatModel.class.getDeclaredMethod("createRequest", Prompt.class, boolean.class);
            method.setAccessible(true);
        }

         prompt = new Prompt("你是公司内部的AI助手，请格式化输出内容到html的<body>标签中", OpenAiChatOptions.builder()
                .responseFormat(ResponseFormat.builder()
                        .type(ResponseFormat.Type.TEXT)
                        .build())
                .toolNames(Set.of("getManageableTableStructures", "getTableSchema","getTableSelector"))
                .build());

        OpenAiApi.ChatCompletionRequest chatRequest = (OpenAiApi.ChatCompletionRequest) method.invoke(deepseekChatModel, prompt, false);
        this.tools=chatRequest.tools();
        resolveToolCallbacks(applicationContext);
        
        return chatRequest;
    }

    public OpenAiApi.ChatCompletionRequest createChatRequestFunctionNote() {
//        ChatRequest.Message system = new ChatRequest.Message("system", "你是公司内部的AI助手，请格式化输出内容到html的<body>标签中");
        if (method == null) {
            try {
                method = OpenAiChatModel.class.getDeclaredMethod("createRequest", Prompt.class, boolean.class);
            } catch (NoSuchMethodException e) {
                log.error("模型反射失败:",e);
                throw new RuntimeException(e);
            }
            method.setAccessible(true);
        }
        prompt = new Prompt("你是一个笔记处理工具的AGI", OpenAiChatOptions.builder()
                .responseFormat(ResponseFormat.builder()
                        .type(ResponseFormat.Type.TEXT)
                        .build())
                .toolNames(Set.of("getNoteTextParsing"))
                .build());
        OpenAiApi.ChatCompletionRequest chatRequest = null;
        try {
            chatRequest = (OpenAiApi.ChatCompletionRequest) method.invoke(deepseekChatModel, prompt, false);
        } catch (IllegalAccessException | InvocationTargetException e) {
            log.error("模型反射失败:",e);
            throw new RuntimeException(e);
        }
        this.tools=chatRequest.tools();
        resolveToolCallbacks(applicationContext);
        return chatRequest;
    }

    public  Map<String, ToolCallback> ToosBeanFetcher() {
        return toolCallbackMap;
    }
    public  Map<String, ToolCallback> resolveToolCallbacks(ApplicationContext applicationContext) {

        GenericApplicationContext genericApplicationContext = new GenericApplicationContext(applicationContext);

        SpringBeanToolCallbackResolver resolver = SpringBeanToolCallbackResolver.builder()
                .applicationContext(genericApplicationContext)
                .build();
        Map<String, ToolCallback> toolCallbackMap = new HashMap<>();
        this.tools.forEach(
                tool -> {
                    log.info("注册函数tools:{}",tool.getFunction().getName());
                    ToolCallback toolCallback = resolver.resolve(tool.getFunction().getName());
                    toolCallbackMap.put(tool.getFunction().getName(), toolCallback);
                }
        );
        // 遍历 Function 类型的 Bean 并解析为 ToolCallback
       this.toolCallbackMap=toolCallbackMap;
        return toolCallbackMap;
    }
}
